﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using RuoVea.ExConfig;
using RuoVea.ExSugar;
using RuoVea.OmiApi.Log.Entitys;
using RuoVea.OmiApi.Log.Service;
using SqlSugar;

namespace RuoVea.OmiApi.Log
{
    /// <summary>
    /// 注入扩展
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 日志管理
        /// </summary>
        /// <param name="services"></param>
        /// <param name="serviceLifetime">Scoped</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IServiceCollection AddOmiLogSetup(this IServiceCollection services, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            services.Configure<DbInitConfig>(AppSettings.Configuration.GetSection("DbInitConfig"));
            return DI(services, null, serviceLifetime);
        }

        /// <summary>
        /// 日志管理
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config"></param>
        /// <param name="serviceLifetime">Scoped</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IServiceCollection AddOmiLogSetup(this IServiceCollection services, IConfiguration config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            if (config == null) throw new ArgumentNullException(nameof(config));
            services.Configure<DbInitConfig>(config);
            DbInitConfig dbInitConfig = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
            return DI(services, dbInitConfig, serviceLifetime);
        }

        /// <summary>
        /// 日志管理
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config"></param>
        /// <param name="serviceLifetime">Scoped</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IServiceCollection AddOmiLogSetup(this IServiceCollection services, Action<DbInitConfig> config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            if (config == null) throw new ArgumentNullException(nameof(config));
            services.Configure(config);
            DbInitConfig dbInitConfig = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
            return DI(services, dbInitConfig, serviceLifetime);
        }

        #region DI
        private static IServiceCollection DI(IServiceCollection services, DbInitConfig dbInitConfig, ServiceLifetime serviceLifetime)
        {
            switch (serviceLifetime)
            {
                case ServiceLifetime.Scoped:
                    services.AddScoped<SysLogDiffService>();
                    services.AddScoped<SysLogExService>();
                    services.AddScoped<SysLogOpService>();
                    services.AddScoped<SysLogVisService>();
                    break;
                case ServiceLifetime.Singleton:
                    services.AddSingleton<SysLogDiffService>();
                    services.AddSingleton<SysLogExService>();
                    services.AddSingleton<SysLogOpService>();
                    services.AddSingleton<SysLogVisService>();
                    break;
                case ServiceLifetime.Transient:
                    services.AddTransient<SysLogDiffService>();
                    services.AddTransient<SysLogExService>();
                    services.AddTransient<SysLogOpService>();
                    services.AddTransient<SysLogVisService>();
                    break;
            }
            return services;
        }
        #endregion

        /// <summary>
        /// 日志管理 - 初始化数据库/初始化种子数据
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddLogInitSetup(this IServiceCollection services)
        {
            Task.Run(() =>
            {
                DbInitConfig config = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
                var _thisRepository = services.BuildServiceProvider().GetRequiredService<ISqlSugarClient>();
                if (config.InitTable && _thisRepository != null)
                {
                    if (_thisRepository.DbMaintenance.IsAnyTable(nameof(SysLogEx), false) || _thisRepository.DbMaintenance.IsAnyTable("sys_log_ex", false)) { }
                    else
                        _thisRepository.CodeFirst.InitTables<SysLogEx>();

                    if (_thisRepository.DbMaintenance.IsAnyTable(nameof(SysLogOp), false) || _thisRepository.DbMaintenance.IsAnyTable("sys_log_op", false)) { }
                    else
                        _thisRepository.CodeFirst.InitTables<SysLogOp>();

                    if (_thisRepository.DbMaintenance.IsAnyTable(nameof(SysLogDiff), false) || _thisRepository.DbMaintenance.IsAnyTable("sys_log_diff", false)) { }
                    else
                        _thisRepository.CodeFirst.InitTables<SysLogDiff>();

                    if (_thisRepository.DbMaintenance.IsAnyTable(nameof(SysLogVis), false) || _thisRepository.DbMaintenance.IsAnyTable("sys_log_vis", false)) { }
                    else
                        _thisRepository.CodeFirst.InitTables<SysLogVis>();

                }
            });
            return services;
        }
    }
}
